﻿using System;
using Service4u2.Json;
using System.Collections.Generic;

namespace MoAds.AdAdapters.AdMob
{
    /// <summary>
    /// The Ad Response from AdMob.
    /// </summary>
    public class AdInfoResponse : IJSONMassager
    {
        // Example response.
        // {"text":"This Prayer Can Change Your Life","url":"http://c.admob.com/c1/3/EkNRoXWQy2EkMXFWshdoS4C7670990088B8004891bfa1c90b83f8c","image_url":"http://c.admob.com/i1/3/EkNRoXWQy2EkMXFWshdoS4C7670990088B8004891bfa1c90b83f8c","jsonp_url":"http://c.admob.com/j1/3/EkNRoXWQy2EkMXFWshdoS4C7670990088B8004891bfa1c90b83f8c","204":"/static/iphone/img/biz.png","6":"url"}
        // formatted for assignment:
        // "{\"text\":\"This Prayer Can Change Your Life\",\"url\":\"http://c.admob.com/c1/3/EkNRoXWQy2EkMXFWshdoS4C7670990088B8004891bfa1c90b83f8c\",\"image_url\":\"http://c.admob.com/i1/3/EkNRoXWQy2EkMXFWshdoS4C7670990088B8004891bfa1c90b83f8c\",\"jsonp_url\":\"http://c.admob.com/j1/3/EkNRoXWQy2EkMXFWshdoS4C7670990088B8004891bfa1c90b83f8c\",\"204\":\"/static/iphone/img/biz.png\",\"6\":\"url\"}\"

        public string text { get; set; }
        public string url { get; set; }
        public string image_url { get; set; }
        public string banner { get; set; }
        public string jsonp_url { get; set; }
        public string tile_url { get; set; }

        #region IJSONMassager Members

        public string MassageJSON(string json)
        {
            // This is a total hack, but there is no documentation anywhere for why you must prepend http://mm.admob.com to the 204 url for the ad image.
            // Nevermind the fact that the 204 value is undocumented as far as I can tell.  
            // Further, AdMob Documentation == garbage.

            var massaged = json
                                .Replace("\"204\":", "\"tile_url\":");

            var idx = massaged.IndexOf("\"tile_url\":");
            if (idx > 0)
                massaged = massaged.Insert(idx + 12, "http://mm.admob.com");

            return massaged;
        }

        #endregion
    }

    /// <summary>
    /// The request to send to the AdMob JSON service
    /// This is kind of esoteric, but it's from the ad mob wiki at http://developer.admob.com/wiki/Requests
    /// </summary>
    public class AdMobRequest
    {   
        public int rt { get; set; }
        public string s { get; set; }
        public int ex { get; set; }
        public string o { get; set; }
        public string f { get; set; }
        public string u { get; set; }
        public string z { get; set; }
    }

    /// <summary>
    /// The AdMob JSON Service.
    /// </summary>
    public class AdMobService : BaseJsonService<AdInfoResponse>
    {
        private const string adMobURL = "http://r.admob.com/ad_source.php";

        public void GetAdInfoAsync(string publisherId, string cookie, string userAgent, bool testMode, List<string> keywords = null)
        {
            var req = new AdMobRequest()
            {
                rt = 0,  // An ad request
                s = publisherId, // our pub id.
                ex = 1, // use the requesting client's ip address.
                o = cookie, // Our cookie string.                
                u = userAgent, // the user agent string
                f = "jsonp", // we want json back
                z = GenerateTimeStamp(), // num of seconds since unix epoch.
            };
            // A helper for turning a classes properties into URL Encoded form data.
            var postData = req.Postify();

            // add the keywords if there are any.
            if (keywords != null && keywords.Count != 0)
                postData += "&k=" + (string.Join("+", keywords.ToArray()));

            // Append the test mode parameter, if applicable.
            if (testMode)
                postData += "&m=test";
            
            // Add the user agent string.
            base.Headers["User-Agent"] = userAgent;
            
            // Start our service call using the underlying WebClient.
            StartServiceCall(adMobURL, HttpMethod.POST, postData);
        }


        /// <summary>
        /// Generates the time stamp from the UNIX Epoch.
        /// </summary>
        /// <returns>A string representation of the number of seconds since the UNIX Epoch.</returns>
        private string GenerateTimeStamp()
        {
            TimeSpan span = (TimeSpan)(DateTime.UtcNow - new DateTime(0x7b2, 1, 1, 0, 0, 0, 0));
            return Convert.ToInt64(span.TotalSeconds).ToString();
        }
    }
}
